package com.gt.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author Administrator
 */
@Slf4j
public class HttpUtil {

    public static JSONObject getPostJson(HttpServletRequest request) {
        return JSONObject.parseObject(getPostString(request));
    }

    public static String getPostString(HttpServletRequest request) {

        StringBuffer buffer = new StringBuffer();
        try {
            InputStream inputStream = request.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        return buffer.toString();
    }

    public static Map<String,Object> getRequestParams(HttpServletRequest request){
        Map<String,Object> params = new HashMap<String, Object>();
        Map<String,String[]> m = request.getParameterMap();
        Iterator<String> it = m.keySet().iterator();
        while (it.hasNext()) {
            String k = (String) it.next();
            String v = ((String[]) m.get(k))[0];
            params.put(k, v);
        }
        return params;
    }

    public static Map<String,Object> getReqParams(HttpServletRequest request){
        Map<String,Object> params = new LinkedHashMap<>();
        Map<String,String[]> m = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : m.entrySet()) {
            params.put(entry.getKey(), entry.getValue()[0]);
        }
        return params;
    }


    public static String orderedAsci(Map<String, Object> dataMap){
        List<String> keys = new ArrayList(dataMap.keySet());

        StringBuffer sbuf = new StringBuffer("");
        String [] arrayToSort = keys.toArray(new String[keys.size()]);
        Arrays.sort(arrayToSort);

        for (int i = 0; i < arrayToSort.length; i++) {
            String key = arrayToSort[i];
            Object value = dataMap.get(key);
            if (value != null && !value.toString().equals("null") && !"".equals(value) && !"null".equals(value)) {
                sbuf.append(key).append("=").append(value).append("&");
            }
        }
        String result = sbuf.toString();
        result = result.substring(0, result.length()-1);
        return result;
    }

    public static String orderedWithEmpty(Map<String, Object> dataMap){
        List<String> keys = new ArrayList(dataMap.keySet());

        StringBuffer sbuf = new StringBuffer("");
        String [] arrayToSort = keys.toArray(new String[keys.size()]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);

        for (int i = 0; i < arrayToSort.length; i++) {
            String key = arrayToSort[i];
            Object value = dataMap.get(key);
            sbuf.append(key).append("=").append(value).append("&");
        }
        String result = sbuf.toString();
        result = result.substring(0, result.length()-1);
        return result;
    }

    public static String getRequestBodyFromMap(Map<String,Object> parametersMap,boolean isUrlEncoding/*,String charset*/) {
        StringBuffer sbuffer = new StringBuffer();
        for(String obj:parametersMap.keySet()){
            String value=(String) parametersMap.get(obj);
            if(StringUtils.isBlank(value)){
                continue;
            }
            if(isUrlEncoding){
                try {
                    value = URLEncoder.encode(value, "utf-8");
                    parametersMap.put(obj, value);
                } catch (UnsupportedEncodingException e1) {
                    log.error(e1.getMessage(), e1);
                }
            }
            sbuffer.append(obj).append("=").append(value).append("&");
        }
        return sbuffer.toString().replaceAll("&$", "");
    }

    public static JSONObject requestApiPost(JSONObject json, String url, RestTemplate restTemplate) {
        log.info("请求地址，{}", url);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept-Encoding","gzip,deflate");
        HttpEntity request = new HttpEntity<>(json.toJSONString(), headers);
        String result = restTemplate.postForObject(url, request, String.class);
        return JSONObject.parseObject(result);
    }
    public static JSONObject requestApiPost(String json, String url, RestTemplate restTemplate) {
        log.info("请求地址，{}", url);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept-Encoding","gzip,deflate");
        HttpEntity request = new HttpEntity<>(json, headers);
        String result = restTemplate.postForObject(url, request, String.class);
        return JSONObject.parseObject(result);
    }

    public static JSONObject requestApiGet(JSONObject json, String url, RestTemplate restTemplate) {
        log.info("请求地址，{}", url);
        Map<String, Object> params = json.toJavaObject(Map.class);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        params.entrySet().stream().forEach(p -> builder.queryParam(p.getKey(), p.getValue()));
        return restTemplate.getForObject(builder.build().toString(), JSONObject.class);
    }
    /**
     * wjh
     * 2021/7/25
     * MultipartFile参数以multipart/form-data协议请求（传入文件流）
     */
    public static JSONObject requestMultipartFile(String url, String key, MultipartFile multipartFile, RestTemplate restTemplate) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        // restTemplate不能发送form表单参数时，MultipartFile和file都不能正确识别，需包装为FileSystemResource才可,可创建临时文件
        File tempFile = File.createTempFile("spw-", multipartFile.getOriginalFilename());
        multipartFile.transferTo(tempFile);
        FileSystemResource fileAsResource = new FileSystemResource(tempFile);

        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add(key,fileAsResource);
        HttpEntity<MultiValueMap<String,Object>> formEntity = new HttpEntity<>(param,headers);
        ResponseEntity<JSONObject> resp = restTemplate.postForEntity(url, formEntity, JSONObject.class);
//        return JSONObject.parseObject(resp.getBody());
        return restTemplate.postForEntity(url, formEntity, JSONObject.class).getBody();
    }
    /**
     * wjh
     * 2021/8/8
     * 请求接口，返回图片流，展示在浏览器上（返回流协议image/jpeg）
     */
    public static void requestPicFile(String url, JSONObject json, HttpServletResponse response, RestTemplate restTemplate) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
//        headers.setContentType(type);
        HttpEntity httpEntity = new HttpEntity<>(json.toJSONString(), headers);
        ResponseEntity<org.springframework.core.io.Resource> entity = restTemplate.postForEntity(url, httpEntity, org.springframework.core.io.Resource.class);
//        ResponseEntity<org.springframework.core.io.Resource> entity = restTemplate.exchange(uri.toString(), HttpMethod.POST,httpEntity, org.springframework.core.io.Resource.class);
        response.setContentType(MediaType.IMAGE_PNG_VALUE);
        ServletOutputStream outputStream = response.getOutputStream();
        org.apache.commons.io.IOUtils.copy(entity.getBody().getInputStream(), outputStream);
        outputStream.flush();
    }
}
